﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace OpenSearchTests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class OSDDTests
    {
        public OSDDTests()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes

        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //

        #endregion Additional test attributes

        [TestMethod]
        [DeploymentItem("simple_osdd.xml")]
        public void TestParseSimpleOsdd()
        {
            System.IO.FileStream stream = new System.IO.FileStream("simple_osdd.xml", System.IO.FileMode.Open);
            OpenSearch.Osdd.OpenSearchDescriptionDocument osdd = new OpenSearch.Osdd.OpenSearchDescriptionDocument(stream);

            Assert.AreEqual("Web Search", osdd.ShortName);

            Assert.AreEqual("Use Example.com to search the Web.", osdd.Description);

            List<string> expectedTags = new List<string> { "example", "web" };
            Assert.IsTrue(expectedTags.SequenceEqual(osdd.Tags));

            ICollection<OpenSearch.Osdd.Url> urls = osdd.Urls;
            Assert.AreEqual(1, urls.Count);
            OpenSearch.Osdd.Url url = urls.ToArray()[0];
            Assert.AreEqual(1, url.IndexOffset); // default value
            Assert.AreEqual("application/rss+xml", url.MimeType);
            Assert.AreEqual("http://example.com/?q={searchTerms}&pw={startPage?}&format=rss", url.Template.ToString());

            Assert.AreEqual("admin@example.com", osdd.Contact);
        }

        [TestMethod]
        [DeploymentItem("detailed_osdd.xml")]
        public void TestParseDetailedOsdd()
        {
            System.IO.FileStream stream = new System.IO.FileStream("detailed_osdd.xml", System.IO.FileMode.Open);
            OpenSearch.Osdd.OpenSearchDescriptionDocument osdd = new OpenSearch.Osdd.OpenSearchDescriptionDocument(stream);

            Assert.AreEqual("Web Search", osdd.ShortName);

            Assert.AreEqual("Use Example.com to search the Web.", osdd.Description);

            List<string> expectedTags = new List<string> { "example", "web" };
            Assert.IsTrue(expectedTags.SequenceEqual(osdd.Tags));

            ICollection<OpenSearch.Osdd.Url> urls = osdd.Urls;
            Assert.AreEqual(3, urls.Count);
            OpenSearch.Osdd.Url url0 = urls.ToArray()[0];
            Assert.AreEqual(1, url0.IndexOffset); // default value
            Assert.AreEqual("application/atom+xml", url0.MimeType);
            Assert.AreEqual("http://example.com/?q={searchTerms}&pw={startPage?}&format=atom", url0.Template.ToString());
            OpenSearch.Osdd.Url url1 = urls.ToArray()[1];
            Assert.AreEqual(1, url1.IndexOffset); // default value
            Assert.AreEqual("application/rss+xml", url1.MimeType);
            Assert.AreEqual("http://example.com/?q={searchTerms}&pw={startPage?}&format=rss", url1.Template.ToString());
            OpenSearch.Osdd.Url url2 = urls.ToArray()[2];
            Assert.AreEqual(1, url2.IndexOffset); // default value
            Assert.AreEqual("text/html", url2.MimeType);
            Assert.AreEqual("http://example.com/?q={searchTerms}&pw={startPage?}", url2.Template.ToString());

            ICollection<OpenSearch.Osdd.Image> images = osdd.Images;
            Assert.AreEqual(2, images.Count);
            OpenSearch.Osdd.Image image0 = images.ToArray()[0];
            Assert.AreEqual(64, image0.Height);
            Assert.AreEqual(64, image0.Width);
            Assert.AreEqual("image/png", image0.MimeType);
            Assert.AreEqual("http://example.com/websearch.png", image0.Uri.ToString());
            OpenSearch.Osdd.Image image1 = images.ToArray()[1];
            Assert.AreEqual(16, image1.Height);
            Assert.AreEqual(16, image1.Width);
            Assert.AreEqual("image/vnd.microsoft.icon", image1.MimeType);
            Assert.AreEqual(new System.Uri("http://example.com/websearch.ico"), image1.Uri);

            ICollection<OpenSearch.Query> queries = osdd.Queries;
            Assert.AreEqual(1, queries.Count);
            OpenSearch.Query query = queries.ToArray()[0];
            Assert.AreEqual("example", query.Role);
            Assert.AreEqual("cat", query.SearchTerms);

            Assert.AreEqual("Example.com Web Search", osdd.LongName);
            Assert.AreEqual("Example.com Development Team", osdd.Developer);

            Assert.AreEqual("\r\n Search data Copyright 2005, Example.com, Inc., All Rights Reserved\r\n", osdd.Attribution);

            Assert.AreEqual("open", osdd.SyndicationRight.ToString());

            Assert.IsFalse(osdd.AdultContent);

            List<string> languages = osdd.Languages.ToList();
            Assert.AreEqual(1, languages.Count);
            Assert.AreEqual("en-us", languages[0]);

            List<string> outputEncodings = osdd.OutputEncodings.ToList();
            Assert.AreEqual(1, outputEncodings.Count);
            Assert.AreEqual("UTF-8", outputEncodings[0]);

            List<string> inputEncodings = osdd.InputEncodings.ToList();
            Assert.AreEqual(1, inputEncodings.Count);
            Assert.AreEqual("UTF-8", inputEncodings[0]);
        }

        [TestMethod]
        [DeploymentItem("ddf_os.xml")]
        public void TestParseDdfOsdd()
        {
            System.IO.FileStream stream = new System.IO.FileStream("ddf_os.xml", System.IO.FileMode.Open);
            OpenSearch.Osdd.OpenSearchDescriptionDocument osdd = new OpenSearch.Osdd.OpenSearchDescriptionDocument(stream);

            Assert.AreEqual("DDF", osdd.ShortName);

            Assert.AreEqual("Query the Metadata Catalog via OpenSearch specifications for query searches", osdd.Description);

            List<string> expectedTags = new List<string> { "ddf", "opensearch", "query" };
            Assert.IsTrue(expectedTags.SequenceEqual(osdd.Tags));

            Assert.AreEqual("bradh@frogmouth.net", osdd.Contact);

            List<OpenSearch.Osdd.Url> urls = osdd.Urls.ToList();
            Assert.AreEqual(5, urls.Count);
            OpenSearch.Osdd.Url url0 = urls[0];
            Assert.AreEqual(1, url0.IndexOffset);
            Assert.AreEqual("application/atom+xml", url0.MimeType);
            Assert.AreEqual("http://192.168.40.180:8181/services/catalog/query?q={searchTerms?}&count={count?}&mt={fs:maxTimeout?}&lat={geo:lat?}&lon={geo:lon?}&radius={geo:radius?}&dtstart={time:start?}&dtend={time:end?}&dtoffset={:offset?}&selector={ddf:selector?}&sort={fs:sort?}&format=atom&type={type?}&version={version?}", url0.Template.ToString());
            OpenSearch.Osdd.Url url1 = urls[1];
            Assert.AreEqual(1, url1.IndexOffset);
            Assert.AreEqual("application/atom+xml", url1.MimeType);
            Assert.AreEqual("http://192.168.40.180:8181/services/catalog/query?q={searchTerms?}&count={count?}&mt={fs:maxTimeout?}&bbox={geo:box?}&dtstart={time:start?}&dtend={time:end?}&dtoffset={ddf:offset?}&selector={ddf:selector?}&sort={fs:sort?}&format=atom&type={type?}&version={version?}", url1.Template.ToString());
            OpenSearch.Osdd.Url url2 = urls[2];
            Assert.AreEqual(1, url2.IndexOffset);
            Assert.AreEqual("application/atom+xml", url2.MimeType);
            Assert.AreEqual("http://192.168.40.180:8181/services/catalog/query?q={searchTerms?}&count={count?}&mt={fs:maxTimeout?}&polygon={geo:polygon?}&dtstart={time:start?}&dtend={time:end?}&dtoffset={ddf:offset?}&selector={ddf:selector?}&sort={fs:sort?}&format=atom&type={type?}&version={version?}", url2.Template.ToString());
            OpenSearch.Osdd.Url url3 = urls[3];
            Assert.AreEqual(1, url3.IndexOffset);
            Assert.AreEqual("application/atom+xml", url3.MimeType);
            Assert.AreEqual("http://192.168.40.180:8181/services/catalog/query?q={searchTerms?}&count={count?}&mt={fs:maxTimeout?}&geometry={geo:geometry?}&dtstart={time:start?}&dtend={time:end?}&dtoffset={ddf:offset?}&selector={ddf:selector?}&sort={fs:sort?}&format=atom&type={type?}&version={version?}", url3.Template.ToString());
            OpenSearch.Osdd.Url url4 = urls[4];
            Assert.AreEqual(1, url4.IndexOffset);
            Assert.AreEqual("text/html", url4.MimeType);
            Assert.AreEqual("http://192.168.40.180:8181/services/catalog/query?q={searchTerms?}&count={count?}&mt={fs:maxTimeout?}&lat={geo:lat?}&lon={geo:lon?}&radius={geo:radius?}&dtstart={time:start?}&dtend={time:end?}&dtoffset={ddf:offset?}&selector={ddf:selector?}&sort={fs:sort?}&format=html&type={type?}&version={version?}", url4.Template.ToString());

            Assert.AreEqual("DDF", osdd.LongName);

            List<OpenSearch.Query> queries = osdd.Queries.ToList();
            Assert.AreEqual(1, queries.Count);
            var q = queries[0];

            OpenSearch.Query query = queries[0];
            Assert.AreEqual("example", query.Role);
            Assert.AreEqual("iraq", query.SearchTerms);

            Assert.AreEqual("DDF Team", osdd.Developer);

            Assert.AreEqual("open", osdd.SyndicationRight.ToString());

            Assert.IsFalse(osdd.AdultContent);

            Assert.IsTrue(osdd.Languages.SequenceEqual(new List<string> { "en-us" }));
            Assert.IsTrue(osdd.OutputEncodings.SequenceEqual(new List<string> { "UTF-8" }));
            Assert.IsTrue(osdd.InputEncodings.SequenceEqual(new List<string> { "UTF-8" }));
        }
    }
}